package rpc2.proxy;

//import rpc2.annotation.Remote;
import rpc2.annotation.RemoteInvoke;
import rpc2.client.ClientRequest;
import rpc2.client.TcpClient;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.stereotype.Component;
import rpc2.param.Response;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Component
public class InvokeProxy implements BeanPostProcessor {

//    初始化之前改为动态代理
    @Override
    public Object postProcessBeforeInitialization(Object bean, String s) throws BeansException {
        Field[] fields=bean.getClass().getDeclaredFields();
        for(Field field:fields){
//            判断RemoteInvokingTest有没有RemoteInvoke注解
            if (field.isAnnotationPresent(RemoteInvoke.class)){
                field.setAccessible(true);
                Map<Method,Class> methodClassMap=new HashMap<Method,Class>();
                putMethodClass(methodClassMap,field);
                Enhancer enhancer=new Enhancer();
                enhancer.setInterfaces(new Class[]{field.getType()});
                //                    用了cglib动态代理 执行userRemote.saveUser()时进行拦截x`
                enhancer.setCallback(new MethodInterceptor() {

                    @Override
                    public Object intercept(Object instance, Method method, Object[] args, MethodProxy Proxy) throws Throwable {
//                        采用netty客户端去调用服务器
                        ClientRequest request=new ClientRequest();
//                        User u=new User();
//                        u.setId(1);
//                        u.setName("张三");
//                        request.setCommand(methodClassMap.get(method).getName()+"."+method.getName());
                        request.setCommand(method.getName());
                        request.setContent(args[0]);
                        Response response= TcpClient.send(request);
                        return response;
                    }
                });
                try {
                    field.set(bean,enhancer.create());
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

            }
        }
        return bean;
    }

//    对属性得所有方法和属性接口类型放入到一个Map中
    private void putMethodClass(Map<Method, Class> methodClassMap, Field field) {
        Method[] methods=field.getType().getDeclaredMethods();
        for (Method m:methods){
            methodClassMap.put(m,field.getType());
        }

    }

    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        return o;
    }
}
